<?php
namespace app\common\model;

use app\common\service\Asiabill;
use app\common\service\Config;
use app\common\service\MaBangErp;
use app\common\service\Paypal;
use think\facade\Db;
use think\facade\View;
use think\model\concern\SoftDelete;

class OrderModel extends BaseModel
{
    use SoftDelete,TraitPay;
    protected $table='order';
    /**
     * @var UserModel|null
     * */
    public static $user_model=null;

    public static $fields_type = [
        ['name'=>'商城订单'],
    ];

    public static $fields_is_back = [
        ['name'=>'-'],
        ['name'=>'申请中'],
        ['name'=>'审核通过'],
        ['name'=>'审核被拒'],
    ];


    protected $json = ['distance_info','extra','pay_info'];


    //订单出发后抵达时间-分钟
    const ORDER_RECEIVE_MINUTE = 5;
    //订单自动完成日期
    const ORDER_AUTO_COMPLETE_DAY = 7;
    //订单完成后-多久发放佣金
    const ORDER_COMMISSION_SEND = 7;
    //预约订单提前多久发送提示
    const ORDER_SERVICE_NOTIFY_SECOND = 1800;
    //订单有效时间--有效时间为2小时  单位秒
    const ORDER_EXP_TIME = 7200;

    //预约订单有效时间--有效时间为5分钟  单位秒
    const ORDER_SUBSCRIBE_EXP_TIME = 300;

    //退款限制时长
    const ORDER_ORDER_BACK_TIME = 604800;

    const ORDER_HANDLE_AWARD = 'award';           //打赏
    const ORDER_HANDLE_ADD_TIME = 'add_time';           //添加时间
    const ORDER_HANDLE_SERVICE = 'service';           //服务中
    const ORDER_HANDLE_RENEW = 'renew';           //订单支付
    const ORDER_HANDLE_PAY = 'pay';           //订单支付
    const ORDER_HANDLE_RECEIVE = 'receive'; //确认收货
    const ORDER_HANDLE_RECEIVE_CANCEL = 'receive_cancel'; //确认收货
    const ORDER_HANDLE_comment = 'comment'; //评论
    const ORDER_HANDLE_SURE = 'sure'; //确定接单
    const ORDER_HANDLE_REMINDER = 'reminder'; //提醒
    const ORDER_HANDLE_SEND = 'send';         //发送
    const ORDER_HANDLE_SEND_CANCEL = 'send_cancel';         //出发取消
    const ORDER_HANDLE_MOD_ADDR = 'mod-addr';         //修改物流地址
    const ORDER_HANDLE_DEL = 'del';           //删除
    const ORDER_HANDLE_CANCEL = 'cancel';     //取消
    const ORDER_HANDLE_FORCE_BACK = 'force_back';     //取消
    const ORDER_HANDLE_CANCEL_MASTER = 'cancel_master';     //技师取消
    const ORDER_HANDLE_EDIT_ADDR = 'edit-addr';     //编辑订单地址
    const ORDER_HANDLE_COMPLETE = 'complete';     //订单完成
    const ORDER_HANDLE_INVOICE = 'invoice';     //发票管理
    const ORDER_RE_TRY = 're_try';     //重复执行开机指令
    const ORDER_FAULT_REPORT = 'fault_report';     //故障报错
    const ORDER_FOLLOW = 'follow';     //订单流程
    const ORDER_CHAT = 'chat';     //可以聊天
    const ORDER_MAP = 'map';     //可以聊天

    const ORDER_STEP_MB_ORDER = 'mb_order';

    const ORDER_HANDLE_RECOVERY = 'recovery';
    const ORDER_CUSTOMER_REMARK = 'c_remark';

    //退款
    const ORDER_BACK_AUTH = 'back_auth';
    const ORDER_BACK_START = 'back';
    const ORDER_BACK_RETRY = 'back_retry';
    const ORDER_BACK_CANCEL = 'back_cancel';
    const ORDER_BACK_detail = 'back_detail';
    const ORDER_BACK_MONEY = 'back_money';

    //支付方式
    public static $fields_pay_way = [
        'platform'=>['name'=>'已支付','value'=>99, 'is_hide'=>1],
        'wxpay'=>['name'=>'微信支付','value'=>2 ,'is_hide'=>0],
        'alipay'=>['name'=>'支付宝支付','value'=>3,'is_hide'=>0],
        'paypal'=>['name'=>'paypal支付','value'=>4,'is_hide'=>0,'class'=>Paypal::class],
        'asiabill'=>['name'=>'asiabill支付','value'=>5,'is_hide'=>0,'class'=>Asiabill::class],
        'money'=>['name'=>'余额支付','value'=>1, 'is_hide'=>0],

    ];


    public static function fields_status(){
        return [
            ['name'=>lang('status_order_wait_pay'),'handle'=>[
                self::ORDER_HANDLE_PAY,
                self::ORDER_CUSTOMER_REMARK=>['is_pay'=>1],
                self::ORDER_HANDLE_CANCEL,
                self::ORDER_HANDLE_RECOVERY,
            ]],
            ['name'=>lang('status_order_sure_pay'),'handle'=>[
                self::ORDER_BACK_MONEY=>['is_pay'=>1],
                self::ORDER_CUSTOMER_REMARK=>['is_pay'=>1],
                self::ORDER_STEP_MB_ORDER=>['mb_state'=>0,'is_pay'=>1],
            ],'follow'=>[
                'is_send'=>['name'=>lang('status_order_wait_send'),'handle'=>[]],
                'is_receive'=>['name'=>lang('status_order_wait_receive'),'handle'=>[self::ORDER_HANDLE_COMPLETE]],
            ]],
            ['name'=>lang('status_order_canceled'),'handle'=>[
                self::ORDER_HANDLE_RECOVERY,
                self::ORDER_CUSTOMER_REMARK=>['is_pay'=>1],
                self::ORDER_BACK_MONEY=>['is_pay'=>1],
                self::ORDER_STEP_MB_ORDER=>['mb_state'=>0,'is_pay'=>1],
            ],'follow'=>[
                'is_cancel'=>['name'=>lang('status_order_canceled'),'value'=>1,'handle'=>[self::ORDER_HANDLE_DEL]],
                'is_force_back'=>['name'=>lang('status_order_force_canceled'),'value'=>1,'handle'=>[self::ORDER_HANDLE_DEL]],
            ]],
            ['name'=>lang('status_order_complete'),'handle'=>[
                self::ORDER_HANDLE_DEL,
                self::ORDER_CUSTOMER_REMARK=>['is_pay'=>1],
                self::ORDER_BACK_MONEY=>['is_pay'=>1],
                self::ORDER_STEP_MB_ORDER=>['mb_state'=>0,'is_pay'=>1],
            ]],
            ['name'=>lang('status_order_back_money'),'color'=>'info','handle'=>[self::ORDER_HANDLE_DEL]],

        ];
    }


    public static function extraIntro()
    {
        $send_per = SysSettingModel::getContent('money','order_send_cancel_per');

        $receive_per = SysSettingModel::getContent('money','order_receive_cancel_per');

        $force_per = SysSettingModel::getContent('money','order_force_back_per');
        return [
            'receive_cancel_intro'=> sprintf("需承担技师的车费和套餐金额的%s", change_to_percent($receive_per)),
            'send_cancel_intro'=> sprintf("需扣除套餐金额的%s", change_to_percent($send_per)),
            'force_back_intro'=> sprintf("需承担技师的车费和套餐金额的%s", change_to_percent($force_per)),
        ];
    }


    //订单剩余支付时间
    public function getReducePaySecond()
    {
        if(!empty($this['status'])){
            return 0;
        }
        $create_time = $this->getData('create_time');
        $reduce_second = $create_time+self::ORDER_SUBSCRIBE_EXP_TIME-time();
        return $reduce_second<=0 ? 0 : $reduce_second;
    }

    //技师活得服务费
    public function getMasterComeIn()
    {
        $money = 0;
        if(!empty($this['master_ser_money']))  $money += $this['master_ser_money'];
        if(!empty($this['master_car_money']))  $money += $this['master_car_money'];
        return $money;
    }

    public function getServicingEndAttr()
    {
        $ser_day = $this['ser_day'];
        $ser_time = $this['ser_time'];
        return $ser_day.' '.$ser_time;
    }

    //获取订单状态
    public function getStatusName()
    {
        $type = $this['type'];
        $status = (int)$this['status'];
        if($type==3){
            $status_info = self::getPropInfo('fields_goods_status',$status);
        }else{
            $status_info = self::getPropInfo('fields_status',$status);
        }
        if(empty($status_info)){
            return ['--',[]];
        }
        $status_name = $status_info['name'];
        $handle = $status_info['handle'];
        if(isset($status_info['follow'])){
            foreach ($status_info['follow'] as $key=>$follow){
                $state = $this[$key];

                if(isset($follow['value']) && $state == $follow['value'] ){
                    $status_name = $follow['name'];
                    $handle = array_merge($handle,$follow['handle']);
                    break;
                }elseif(!isset($follow['value']) && empty($state)){
                    $status_name = $follow['name'];
                    $handle = array_merge($handle,$follow['handle']);
                    break;
                }
            }
        }
        $handle = $this->getHandleAction($handle);


        return [$status_name,$handle];
    }


    //所有可用支付
    public static function getAllPayWay()
    {
        $data = [];
        foreach (self::getPropInfo('fields_pay_way') as $key=>$vo){
            if(empty($vo['is_hide'])){
                $data[] = $key;
            }
        }
        return $data;
    }

    public function checkOrderPayState()
    {
        if(!empty($this['is_pay'])){
            throw new \Exception("订单未处于可支付状态");
        }
    }

    //获取价格清单
    public function getPriceList()
    {
        $data = [];
        $other_money = $this['other_money'];
        $open_vip_day = $this['open_vip_day'];
        $goods_list = $this->getRelation('linkGoods');
        if(!empty($goods_list) && !$goods_list->isEmpty()){
            foreach ($goods_list as $item){
                $data[] = [
                    'name'=>$item['name'],
                    'price'=>$item['price'],
                ];
            }
        }

        if(!empty($open_vip_day)){
            $data[] = [
                'name' => '开通vip',
                'money' => $other_money,
            ];
        }

        return $data;
    }


    /**
     * 通知
     * @param  UserModel    $user_model 用户id
     * @param  array    $types 订单类型
     * @return int
     */
    public static function getNoReadCount(BaseModel $user_model=null,array $types = [])
    {
        if(empty($user_model)){
            return 0;
        }
        $where = [];
        list($extra_where,$_)=self::getStateWhere('wait_pay');
        $where[] = $extra_where;
        $where[] = ['type','in',$types];
        if($user_model instanceof MasterModel){
            $where[] = ['mid','=',$user_model['id']];
        }else{
            $where[] = ['uid','=',$user_model['id']];
        }
        return self::where($where)->count();

    }

    public static function getStateWhere($activeState)
    {
        $where = $whereOr =[];
        if($activeState=='cancel'){ //取消
            $where[] = ['status','=',2];
        }elseif($activeState=='sure_pay'){ //已付款
            $where[] = ['is_pay','=',1];
        }elseif($activeState=='wait_pay'){ //待付款
            $where[] = ['status','=',0];
        }elseif($activeState=='wait_rec'){ //待收获
            $where[] = ['status','=',1];
            $where[] = ['is_send','=',1];
            $where[] = ['is_receive','=',0];
        }if($activeState=='send'){ //待出发
            $where[] = ['status','=',1];
            $where[] = ['is_send','=',0];
        }elseif($activeState=='receive'){ //待抵达
            $where[] = ['status','=',1];
            $where[] = ['is_send','=',1];
            $where[] = ['is_receive','=',0];
        }elseif($activeState=='wait_complete'){ //待完成
            $where[] = ['status','=',1];
            $where[] = ['is_receive','=',1];
            $where[] = ['is_complete','=',0];
        }elseif($activeState=='completed'){ //已完成
            $where[] = ['status','=',3];
        }elseif($activeState=='running'){ //进行中
            $where[] = ['status','=',1];
            $where[] = ['is_complete','=',0];
        }elseif($activeState=='wait_comment'){ //待评价
            $where[] = ['status','=',3];
        }elseif($activeState=='refund'){ //售后
            //取消状态
            $whereOr[] = [['status','=',2]];
            //已完成-可以申请售后
            $whereOr[] = [['status','=',3],['complete_time','>=',time()-self::ORDER_ORDER_BACK_TIME]];
            //售后中
            $whereOr[] = ['is_back','>',0];
        }
        return [$where,$whereOr];
    }

    /**
     * 页面数据
     * @param array $input_data 图片类型
     * @throws
     * @return \think\Paginator
     * */
    public static function getPageData(array $input_data = [])
    {
        $orderMode = $input_data['orderMode']??'';
        $activeState = $input_data['activeState']??'';
        $limit = $input_data['limit']??null;
//        $type = empty($input_data['type'])?0:$input_data['type'];
        $where = $whereOr = [];
//        $where[] = ['type','=',$type];
//        if(app()->http->getName()!='admin'){
//            $where[] = ['status','=',1];
//        }

        if($orderMode=='normal'){
            $where[] = ['type','=',0];
        }elseif($orderMode=='custom'){
            $where[] = ['type','=',1];
        }

        list($state_where,$state_whereOr)=self::getStateWhere($activeState);
        $where = array_merge($where,$state_where);
        $whereOr = array_merge($whereOr,$state_whereOr);


        $keyword = trim($input_data['keyword']??'');
        !empty($keyword) && $where[] = ['no','like','%'.$keyword.'%'];

        //业务员id
        if(!empty($input_data['dis_uid'])){
            $where[] = ['dis_uid','=', $input_data['dis_uid'] ];
        }
        //用户id
        if(!empty($input_data['user_id'])){
            $where[] = ['uid','=', $input_data['user_id'] ];
        }
        //用户id
        if(isset($input_data['uid'])){
            $where[] = ['uid','=', $input_data['uid'] ];
        }
        //订单id
        if(!empty($input_data['order_id'])){
            $where[] = ['id','=', $input_data['order_id'] ];
        }
        if(isset($input_data['id'])){
            $where[] = ['id','=', $input_data['id'] ];
        }
        //技师id
        if(isset($input_data['check_master_id'])){
            $where[] = ['mid','=', $input_data['check_master_id'] ];
        }
        //技师id
        if(!empty($input_data['master_id'])){
            $where[] = ['mid','=', $input_data['master_id'] ];
        }
        //技师id
        if(!empty($input_data['mch_id'])){
            $where[] = ['mch_id','=', $input_data['mch_id'] ];
        }
        //商品名
        if(!empty($input_data['goods_name'])){
            $where[] = ['goods_name','like', '%'.$input_data['goods_name'].'%' ];
        }
        //商品名
        if(!empty($input_data['goods_sku'])){
            $where[] = ['goods_sku','like', '%'.$input_data['goods_sku'].'%' ];
        }
        //email
        if(!empty($input_data['email'])){
            $where[] = ['email','like', '%'.$input_data['email'].'%' ];
        }
        if(!empty($input_data['customer_email'])){
            $where[] = ['email','like', '%'.$input_data['customer_email'].'%' ];
        }
        if(!empty($input_data['customer_name'])){
            $where[] = ['name','like', '%'.$input_data['customer_name'].'%' ];
        }
        //email
        if(!empty($input_data['phone'])){
            $where[] = ['phone','like', '%'.$input_data['phone'].'%' ];
        }
        //事件范围查询
        if(!empty($input_data['search_date']) && is_array($input_data['search_date']) && count($input_data['search_date'])==2){
            $input_data['start_date'] = $input_data['search_date'][0];
            $input_data['end_date'] = $input_data['search_date'][1];
        }
        //按时间查询
        $start_date = empty($input_data['start_date'])?'':trim($input_data['start_date']);
        $start_time = empty($start_date)?'':strtotime($start_date);
        $end_date = empty($input_data['end_date'])?'':trim($input_data['end_date']);
        $end__time = empty($end_date)?'':strtotime('+1 day',strtotime($end_date));
        if(!empty($start_time) && !empty($end__time)){
            $where[] = ['create_time','>=',$start_time];
            $where[] = ['create_time','<=',$end__time];
        }elseif(!empty($start_time)){
            $where[] = ['create_time','>=',$start_time];
        }elseif(!empty($end__time)){
            $where[] = ['create_time','<=',$end__time];
        }


        $with = ['linkUser','linkGoods','linkAddr','linkLogistics'];
//        dump($where);exit;
        return self::with($with)->where($where)->where(function($query)use($whereOr){
            $query->whereOr($whereOr);
        })->order('id desc')->paginate($limit);
    }


    private static function checkGoods(array $input_data=[])
    {
        $id = $input_data['id']??0;
        $attr_id = $input_data['attr_id']??0;

        return ProProjectModel::getPageData([
            'id'=>$id,
            'attr_ids'=>empty($attr_id)?[]:[$id=>$attr_id]
        ]);
    }



    //处理下单数据
    public static function handleOrderGoods(array $input_data=[])
    {
        //免费费用
        $locationInfo = empty($input_data['locationInfo']) || !is_array($input_data['locationInfo']) ? []: $input_data['locationInfo'];
        $country = $locationInfo['country']??'';
        $tip_money = empty($input_data['tip_money']) ? 0 : floatval($input_data['tip_money']);
//        $express_money = floatval(SysSettingModel::getContent('free','express_money'));
//        $express_list = SysSettingModel::getContent('free','express_money_intro_shape');
        $orderInfo = empty($input_data['orderInfo']) || !is_array($input_data['orderInfo'])?[]:$input_data['orderInfo'];//订单信息
        $express_id = intval($orderInfo['express_id']??0);

//        if(count($express_list)<=$express_index) $express_index = 0;
        $goods_list = self::getGoodsData($input_data);

        //扩展数据
        $extra_info = [

            'total_goods_money' => 0,

            'total_buy_num' => 0,
            'total_weight' => 0,
            'total_tip_money' => $tip_money,

            'total_tax_money' => 0,
            'total_freight_money' => 0,
        ];


        foreach ($goods_list as $item){

            $weight = floatval(empty($item['sku_weight']) ? $item['weight'] : $item['sku_weight']);
            $sold_price = empty($item['sold_price'])?0:$item['sold_price'];


            $buy_num = $item['buy_num']??1;

            //产品总额
            $extra_info['total_goods_money'] += $sold_price*$buy_num;
            $extra_info['total_weight'] += $weight*$buy_num;
            $extra_info['total_buy_num'] += $buy_num;
            //税费
            $extra_info['total_tax_money'] += $item['tax_money']??0;

        }
        $express_info = null;
        if(!empty($express_id)){
            $freight_list = PlatformFreightPlanModel::getFreightList($country,$extra_info['total_goods_money'],$extra_info['total_weight'],['id'=>$express_id]);
            if(empty($freight_list)) throw new \Exception(lang('err_order_express_selected'));
            $express_info = $freight_list[0];
            $extra_info['total_freight_money'] = $express_info['money'];
        }




        return [$goods_list, $extra_info,$express_info];

    }

    //下单商品处理--获取商品
    public static function getGoodsData($input_data )
    {
        //绑定用户模型
        $session_id = $input_data['session_id']??0;
        $user_id = $input_data['uid']??0;
        $channel = $input_data['channel'] ?? '';//购买渠道

        //直接购买商品流程
        $goods_id = $input_data['goods_id']??0;
        $sku_id = $input_data['sku_id']??0;
        $buy_num = $input_data['num']??1;

        $goods_data = [];
        if($channel=='cart'){
            $goods_data = UserCartModel::getAllData(['channel'=>$channel,'uid'=>$user_id,'session_id'=>$session_id]);
        }elseif($channel=='cart_custom'){
            $goods_data = UserCartCustomModel::getAllData(['channel'=>$channel,'uid'=>$user_id,'session_id'=>$session_id]);
        }else{
            GoodsModel::getPageData(['id'=>$goods_id])->each(function($item)use(&$goods_data,$sku_id,$buy_num){
                //获取商家信息
                $merchant = $item->getRelation('linkMerchant');
                $mch_id = $merchant['id']??0;
                //绑定sku属性
                $item->sku_id = $sku_id;
                //购买数量
                $item->setAttr('buy_num',$buy_num);
                $key = 'mch_'.$mch_id;
                $goods_data[$key] = [
                    'mch_info' => $merchant,
                    'goods_list'=>[$item],
                ];
            });
        }

        return $goods_data;

    }



    public static function handleOrderData(array $input_data=[],UserModel $user_model=null)
    {
        $addr_id = $input_data['addr_id']??0;
        $user_id = $input_data['uid']??0;

        //获取地址
        $model_addr = null;
        if($user_id){
            $addr_where = [];
            $addr_where[] = ['uid','=',$user_id];
            if(!empty($addr_id)){
                $addr_where[] = ['id','=',$addr_id];
            }
            $model_addr = UserAddrModel::where($addr_where)->find();
        }

        $buy_num = empty($input_data['num']) ? 1 : $input_data['num'] ;
        $goods_data = self::checkGoods($input_data);

        //扩展数据
        $extra_info = [
            'total_goods_money' => 0,
            'total_buy_num' => $buy_num,
            'total_commission_money' => 0,
        ];

        foreach ( $goods_data as $item ) {
            $sold_attr_info = $item->getSoldInfoAttr();
            $ser_minute = $sold_attr_info['minute'];
            $cal_sold_price =  $item['sold_price'];

            $item->cal_sold_price = $cal_sold_price;
            $item->buy_num = $buy_num;

            $commission = empty($item['commission']) ? 0 : $item['commission'];
            $extra_info['total_goods_money'] += $cal_sold_price*$buy_num;
            $extra_info['total_commission_money'] += $commission;
        }
        return  [$goods_data, $model_addr,$extra_info,$ser_minute];
    }


    //确认订单
    public static function confirm(UserModel $user_model=null,array $input_data = [])
    {


        $emailInfo = empty($input_data['emailInfo'])|| !is_array($input_data['emailInfo'])? []: $input_data['emailInfo'];//
        $email = $input_data['emailInfo']['email']??'';//
        $session_id = $input_data['session_id']??'';//
        $locationInfo =  empty($input_data['locationInfo'])|| !is_array($input_data['locationInfo'])? []: $input_data['locationInfo'];//配送地址信息
        $channel = $input_data['channel']??'';//渠道
        $coupon_id = $input_data['coupon_id']??0;//优惠券id
        $pay_way = $input_data['pay_way']??'';//支付方式

        if(empty($email)) throw new \Exception(lang('input_email'));
        if(!valid_email($email)) throw new \Exception(lang('err_input_email'));
        if(empty($pay_way)) throw new \Exception(lang('err_order_pay_way'));
        if(!array_key_exists($pay_way,self::$fields_pay_way)) throw new \Exception(lang('err_order_pay_way_exists',['pay_way'=>$pay_way]));


        if(empty($locationInfo)) throw new \Exception(lang('error_location_info'));
        if(empty($locationInfo["country"]))  throw new \Exception(lang('err_location_info_param',['param'=>'country']));
        if(empty($locationInfo["first_name"]))  throw new \Exception(lang('err_location_info_param',['param'=>'first_name']));
        if(empty($locationInfo["last_name"]))  throw new \Exception(lang('err_location_info_param',['param'=>'last_name']));
//        if(empty($locationInfo["suite"]))  throw new \Exception(lang('err_location_info_param',['param'=>'suite']));
//        if(empty($locationInfo["street"]))  throw new \Exception(lang('err_location_info_param',['param'=>'street']));
//        if(empty($locationInfo["state"]))  throw new \Exception(lang('err_location_info_param',['param'=>'state']));
//        if(empty($locationInfo["city"]))  throw new \Exception(lang('err_location_info_param',['param'=>'city']));
//        if(empty($locationInfo["postcode"]))  throw new \Exception(lang('err_location_info_param',['param'=>'postcode']));
        if(empty($locationInfo["phone"]))  throw new \Exception(lang('err_location_info_param',['param'=>'phone']));

        //验证国家是否再排除范围内
        $remove_city = SysSettingModel::getContent('normal','remove_city_comma');
        if(!empty($remove_city) && in_array($locationInfo['country'],$remove_city)){
            throw new \Exception(lang('err_order_logistic_country_disabled',['country'=>$locationInfo['country']]));
        }


        list($goods_list,$extra_info,$express_info) = self::handleOrderGoods($input_data);

        if(empty($goods_list) ) throw new \Exception(lang('err_order_goods_empty'));

        $remark = trim($input_data['remark']??'');

        $goods_name = $goods_sku = "";
        $all_goods_tags = [];

        $min_gift_goods = null;
        foreach ($goods_list as $item) {
            $is_gift = $item['is_gift'];
            if($is_gift && (empty($min_gift_goods) || $item['sold_price'] < $min_gift_goods['sold_price'])){
                $min_gift_goods = $item;
            }
            //获得佣金
            $goods_info = $item->apiNormalInfo();
            $goods_name .= $item['name'].';;';
            $goods_sku .= $goods_info['sku_name'].';;';
            $goods_tags = empty($item['tags'])?[]:array_values(array_filter(explode(',', $item['tags'])));
            $all_goods_tags = array_merge($all_goods_tags, $goods_tags);
        }

        $gift_money = 0; //礼品免费金额
        $sys_gift_money = SysSettingModel::getContent('free','gift_money');
        $sys_gift_money = empty($sys_gift_money)?0:round($sys_gift_money,2);


        $coupon_model =null;
        if(!empty($coupon_id)){
            $coupon_model = CouponModel::where(['status'=>1,'id'=>$coupon_id])->find();
            //检测优惠券是否过期
            if(empty($coupon_model)){
                throw new \Exception(lang('err_coupon_use_no_exist'));
            }
            $coupon_dis_goods_tags = empty($coupon_model['dis_goods_tags']) ? [] : array_values(array_filter(explode(',',$coupon_model['dis_goods_tags'])));
            if(!empty($coupon_dis_goods_tags) && array_intersect($all_goods_tags,$coupon_dis_goods_tags)){
                throw new \Exception(lang('err_coupon_dis_goods_tags_exist'));
            }
            //验证邮箱是否可以用
            if(!empty($coupon_model['emails']) && stripos($coupon_model['emails'],$email)!==false){
                throw new \Exception(lang('err_coupon_use_range_disabled'));
            }

        }



        try{
            \think\facade\Db::startTrans();


            $goods_total_money = $extra_info['total_goods_money'] ?? 0; //产品总金额

            $first_name = $locationInfo['first_name']??'';
            $last_name = $locationInfo['last_name']??'';
            //订单数据
            $model_order = new self();
            $model_order->setAttr('type',$channel=='cart_custom' ? 1 : 0);
            $model_order->session_id = $session_id;
            $model_order->email = $emailInfo['email']??'';
            $model_order->setAttr('name',$last_name.' '.$first_name);
            $model_order->phone = $locationInfo['phone']??'';
            $model_order->uid = empty($user_model)?0:$user_model['id'];
            $model_order->dis_money = 0;//总优惠金额
            $model_order->no = self::getDateNo('01');

            //金钱信息

            $model_order->goods_money = $goods_total_money*1;

            if($min_gift_goods && $model_order->goods_money > $sys_gift_money){
                $gift_money = $min_gift_goods['sold_price'];
            }

            $model_order->dis_money = $model_order->dis_money + $gift_money; //礼品免费
            $model_order->gift_money = $gift_money; //礼品免费
            $model_order->tax_money = $extra_info['total_tax_money'] ?? 0; //税费
            $model_order->freight_money = $extra_info['total_freight_money'] ?? 0; //运费
            $model_order->freight_id = empty($express_info['id'])?null:$express_info['id']; //运费
            $model_order->freight_name = empty($express_info['name'])?null:$express_info['name']; //运费
            $model_order->tip_money = $extra_info['total_tip_money'] ?? 0; //小费





            //订单总金额
            $model_order->money = $goods_total_money + $model_order->freight_money + $model_order->tax_money+$model_order->tip_money;

            $pay_money = $model_order->money; //支付金额

            if(!empty($coupon_model)){
                $model_order->coupon_id = $coupon_model['id'];
                $model_order->coupon_dis_money = $coupon_model['money'];
                $model_order->dis_money +=  $model_order->coupon_dis_money ;
            }

            //实际支付金额扣除优惠金额
            $pay_money = $pay_money - $model_order->dis_money;



            //实际支付金额扣除优惠金额
//                dump($pay_money);exit;
            $model_order->pay_money = $pay_money <= 0 ? 0 : $pay_money;

            $model_order->total_num = $extra_info['total_buy_num'] ?? 0;
            $model_order->goods_name = empty($goods_name)?null: mb_substr($goods_name,0,480);
            $model_order->goods_sku = empty($goods_sku)?null: mb_substr($goods_sku,0,480);

            //需要使用的积分

            $model_order->remark =  $remark;
            //保存订单信息
            $model_order->save();


            //购物车过来删除购物车内容
//            if ($channel == 'cart' && (!empty($user_model['id']) || !empty($session_id)) ) {
//                $cart_where = [];
//                if(!empty($user_model['id'])){
//                    $cart_where[] = ['uid', '=', $user_model['id']];
//                }else{
//                    $cart_where[] = ['session_id', '=', $session_id];
//                }
//                //购物车过来删除购物车内容
//                UserCartModel::where($cart_where)->delete();
//            }




            //保存收货地址
            $model_order_addr = new OrderAddrModel();
            $model_order_addr->setAttrs([
                'oid' => $model_order->id,
                "country" => $locationInfo['country']??'',
                "first_name" => $first_name,
                "last_name" => $last_name,
                "suite" => $locationInfo['suite']??'',
                "street" => $locationInfo['street']??'',
                "state" => $locationInfo['state']??'',
                "city" => $locationInfo['city']??'',
                "postcode" => $locationInfo['postcode']??'',
                "phone" => $locationInfo['phone']??'',
            ]);
            $model_order_addr->save();

            //商品数据
            $order_goods_data = [];

            foreach ($goods_list as $item) {
                //获得佣金
                $goods_info = $item->apiNormalInfo();
                $cart_list = $goods_info['cart_list']??[];
                $info = [
                    'mid' => $user_model['id'],
                    'type' => $model_order['type'],
                    'order_no' => $model_order['no'],//绑定订单号
                    'uid' => $model_order['uid'],
                    'gid' => $goods_info['id'],
                    'gtemp_no' => $item['temp_no'],
                    'gno' => $item['no'],
                    'gcode' => $item['code'],
                    'price' => $goods_info['sold_price'], //实际购买价
                    'sku_id' => $goods_info['sku_id'],
                    'sku_name' => $goods_info['sku_name'],
                    'sku_img' => $goods_info['sku_img'],
                    'num' => $goods_info['buy_num'],
                    'name' => $goods_info['name'],
                    'img' => $goods_info['cover_img'],
                    'extra' => json_encode($goods_info),//保存商品原始数据
                ];
                if(!empty($cart_list)){
                    foreach ($cart_list as $cart_item){
                        $info['logo'] = $goods_info['cart_logo']??'';
                        $info['logo_list'] = json_encode($goods_info['cart_logo_list']??[],JSON_UNESCAPED_UNICODE);
                        $info['num'] = 1;
                        $info['cond_remark'] = $goods_info['cart_remark']??'';
                        $info['cond_name'] = $cart_item['name']??'';
                        $info['cond_color'] = $cart_item['color']??'';
                        $info['sku_name'] = $cart_item['size']??'';
                        array_push($order_goods_data, $info);
                    }
                }else{
                    array_push($order_goods_data, $info);
                }
            }
            $model_order->linkGoods()->saveAll($order_goods_data);
            if (empty($model_order->pay_money)) {
                $model_order->setAttr('is_pay',1); //订单已付款
                $model_order->_sure_pay(); //直接处理确认订单流程
            }
            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollBack();
            throw new \Exception($e->getMessage());
        }

        //发送邮件
        $model_order->sendEmail('create');

        if(!empty($model_order['coupon_id'])){ //添加优惠券使用记录
            CouponUserModel::createUse($model_order,$model_order['coupon_id']);
        }

        return $model_order;
    }

    public static function recovery(array $input_data = [])
    {
        $order_id = $input_data['id']??'';
        $email_temp_id = $input_data['email_temp_id']??'';
        $mode = $input_data['mode']??'1';
        $pay_money = $input_data['pay_money']??'';
        $intro= trim($input_data['intro']??'');

        if(empty($email_temp_id)) throw new \Exception("请选择发送模板");
        if(empty($order_id)) throw new \Exception("参数异常:id");
        if(empty($intro)) throw new \Exception("请输入恢复备注");

        $order_model = self::find($order_id);
        if(empty($order_model)) throw new \Exception("订单不存在或已被删除");

        $order_model->setAttrs([
            'pay_money'=>$pay_money,
            'no'=>self::getDateNo('02'),
            'status'=>0,
            'create_time'=>time(),
        ]);
        $order_model->setAttrs([
            'recovery_intro'=>$intro,
            'recovery_time'=>date('Y-m-d H:i:s'),
        ]);
        $order_model->save();
        //发送邮件
        $order_model->sendEmail('recovery',$email_temp_id);

    }


    //发送邮件
    public function sendEmail($mode,$email_temp_id=null)
    {
        //发送邮件
        list($status_name,$handle_action) = $this->getStatusName();
        $logisticInfo = $this->linkLogistics;

        $addrInfo = $this->linkAddr;
        $back_money = 0;
        if($mode=='create'){ //已创建

        }elseif($mode=='paid'){ //已付款

        }elseif($mode=='logistic'){ //物流变动

        }elseif($mode=='recovery'){ //订单恢复

        }elseif($mode=='customer'){ //客服

        }elseif($mode=='back_money'){ //退款
            $back_money = self::where(['id'=>$this['id']])->value('back_money');
        }elseif($mode=='other'){ //其它

        }else{
            return;
        }

        $where = [];
        if(!is_null($email_temp_id)){
            $where[] =['id','=',$email_temp_id];
        }else{
            $where[] = ['status','=',1];
            $where[] = ['type','=',"order-{$mode}"];
        }

        //今天成交了多少单
        $check_where = [];
        $check_where[] =['is_pay','=',0];
        $check_where[] =['create_time','>',strtotime(date('Y-m-d'))];
        $today_order_count = self::where($check_where)->count();
        PlatformEmailTempModel::where($where)->select()->each(function($item)use($mode,$addrInfo,$logisticInfo,$status_name,$handle_action,$today_order_count,$back_money){
            $body = View::display($item['content'],[
                'orderModel'=>$this,
                'addrInfo'=>$addrInfo,
                'logisticInfo'=>$logisticInfo,
                'status_name'=>$status_name,
                'handle_action' => $handle_action,
                'today_order_count' => $today_order_count,
                'back_money' => $back_money,
            ]);
//            $body = View::fetch(root_path('admin-temp/nepadmin/views/email-temp')."order-{$mode}.html",[
//                'orderModel'=>$this,
//                'logisticInfo'=>$logisticInfo,
//                'status_name'=>$status_name,
//                'handle_action' => $handle_action,
//            ]);
            $send_data = function($email,$body,$item,$mode,$send_time=null){
                return [
                    'tid'=>$item['id'],
                    'mode'=>$mode,
                    'order_id'=>$this['id'],
                    'send_time'=>$send_time,//发送时间
                    'rec_mail'=>$email,
                    'body'=> $body,
                    'subject' => $item['name'],
                    'alt_body' => lang('email_order_alt_body'),
                ];
            };
            if($mode=='customer'){//发送客服
                $customer_email = SysSettingModel::getContent('normal','email_notice_comma');
                if(!empty($customer_email) && is_array($customer_email)){
                    foreach ($customer_email as $email){
                        EmailLogsModel::send($send_data($email,$body,$item,$mode));
                    }
                }
            }else{
                //创建弃单发送邮件
                if($mode=='create'){
                    $recovery_hours = SysSettingModel::getContent('email','send_email_comma');
                    if(!empty($recovery_hours)){
                        $add_hours = 0;
                        PlatformEmailTempModel::where(['status'=>1,'type'=>'order-recovery'])->select()->each(function($item,$index)use(&$add_hours,$recovery_hours,$send_data,$mode,$logisticInfo,$status_name,$handle_action,$today_order_count){
                            if(isset($recovery_hours[$index])){
                                $hours = $recovery_hours[$index]??0;
                                $body = View::display($item['content'],[
                                    'orderModel'=>$this,
                                    'logisticInfo'=>$logisticInfo,
                                    'status_name'=>$status_name,
                                    'handle_action' => $handle_action,
                                    'today_order_count' => $today_order_count,
                                ]);
                                $add_hours = $add_hours+$hours;
                                EmailLogsModel::send($send_data($this['email'],$body,$item,'order-recovery',date('Y-m-d H:i:s',time()+$add_hours*3600)));
                            }

                        });
                    }
                }else{
                    EmailLogsModel::send($send_data($this['email'],$body,$item,$mode));
                }
            }

        });



    }


    public static function getOrderPayInfo(OrderModel $model_order,$pay_way,array $input_data = [])
    {
        $session_id = $input_data['session_id']??'';
        if(!empty($model['status'])) throw new \Exception(lang('err_order_no_pay_state'));
        if(!empty($model['is_pay'])) throw new \Exception(lang('err_order_sure_pay'));
        $currency = 'USD'; //货币
        //回调地址
        $return_url = app()->request->domain().'/user/order/order_id/'.$model_order['id'].'?'.config('session.var_session_id').'='.$session_id;
        //取消地址
        $cancel_url = $return_url;

//        $return_url = url('pay/notify',['order_id'=>$model_order['id'],'order_no'=>$model_order['no']],false,true)->build();
//        $cancel_url = url('pay/cancel',['order_id'=>$model_order['id'],'order_no'=>$model_order['no']],false,true)->build();

        $model_order_addr = OrderAddrModel::where(['oid'=>$model_order['id']])->find();
        $third_order_goods_data = [];
        OrderGoodsModel::where(['oid'=>$model_order['id']])->select()->each(function($item)use(&$third_order_goods_data){
            array_push($third_order_goods_data,[
                "productName"=> str_replace(['&' ,'“' ,'‘', '<' ,'>'],'',$item['name'].'['.$item['sku_name'].']'),
                "quantity"=>$item['num'],
                "price"=>$item['price']
            ]);
        });
        if($pay_way=='paypal') {
            //回调地址
            $return_paypal_url = app()->request->domain().'/order/paypalCheckDetail/order_id/'.$model_order['id'].'?'.config('session.var_session_id').'='.$session_id;
            //取消地址
            $result = Paypal::checkout_orders($model_order['id'],$model_order['no'],(string)$model_order['pay_money'],$return_paypal_url,$cancel_url);
            if(!empty($result) && isset($result['links'])){
                foreach ($result['links'] as $link){
                    if($link['rel']=='approve'){
                        $model_order->setAttr('paypal_orderid',$result['id']);
                        $model_order->save();
                        return ['url'=>$link['href']];
                    }
                }
                throw new \Exception(lang('err_paypal_param',['param'=>':link_empty']));
            }
            throw new \Exception(lang('err_paypal_param',['param'=>':result_err']));
        }elseif($pay_way=='asiabill') {
            //支付回调通知地址
            $notify_url = app()->request->domain().'/pay/notify_asiabill/order_id/'.$model_order['id'].'/order_no/'.$model_order['no'];
            $payOrderInfo = [
                'form_url'=>Config::pay_asiabill('debug')=='test'?'https://testpay.asiabill.com/Interface/V2':'https://pay.asiabill.com/Interface/V2',
                'merNo'=>Config::pay_asiabill('mer_no'),
                'gatewayNo'=>Config::pay_asiabill('gateway_no'),
                'orderNo'=>$model_order['no'],
                'orderCurrency'=>$currency,
                'orderAmount'=>(string)$model_order['pay_money'],
                'callbackUrl'=> $notify_url,
                'returnUrl'=> $return_url,
                'firstName'=>$model_order_addr['first_name'],
                'lastName'=>$model_order_addr['last_name'],
                'email'=>$model_order->email,
                'phone'=>$model_order_addr['phone'],
                'paymentMethod'=>'Credit Card',
                'country'=>$model_order_addr['country'],
                'state'=>$model_order_addr['state'],
                'city'=>$model_order_addr['city'],
                'address'=>$model_order_addr['street'],
                'zip'=>$model_order_addr['postcode'],
                'goods_detail'=> json_encode($third_order_goods_data),
            ];
            $payOrderInfo['signInfo'] = Asiabill::getSign($payOrderInfo['merNo'].$payOrderInfo['gatewayNo'].$payOrderInfo['orderNo'].$payOrderInfo['orderCurrency'].$payOrderInfo['orderAmount'].$payOrderInfo['returnUrl']);
//            dump(sprintf("merNo=>%s \n gatewayNo=>%s \n orderNo=>%s \n orderCurrency=>%s \n orderAmount=>%s \n returnUrl=>%s \n signkey=>%s \n signInfo=>%s",
//                $payOrderInfo['merNo'],$payOrderInfo['gatewayNo'],$payOrderInfo['orderNo'],$payOrderInfo['orderCurrency'],$payOrderInfo['orderAmount'],$payOrderInfo['returnUrl'],$signkey,$signInfo));exit;

//            $payOrderInfo['signInfo'] = $signInfo;
            return $payOrderInfo;

        }else{
            return [];
        }
    }



    //订单返还处理事件
    public static function onOrderBackHandle($model)
    {
        if(empty($model->cancel_back_handle_time)){
            $user_model = UserModel::find($model['uid']);
            $change_integral = $user_model['integral'];
            //更新订单状态
            $update_state = self::update(['cancel_back_handle_time'=>time()],[
                'id'=>$model['id'],
                'cancel_back_handle_time'=>$model['cancel_back_handle_time'],
            ]);
            if($update_state->getNumRows()){

                if($model['integral']>0){
                    //优惠券状态调整-返还优惠券
                    $integral = empty($model['integral'])?0:$model['integral'];
                    UserModel::update(['integral'=>\think\facade\Db::raw('integral+'.$integral)],['id'=>$model['uid']]);
                    //创建日志
                    UserLogsModel::recordData(1,$model['uid'],$integral,"订单取消返回使用能量值,单号:".$model['no'],['q_money'=>$change_integral,'h_money'=>$change_integral+$integral]);
                }


                if($model['coupon_id']>0 ){
                    //优惠券状态调整-返还优惠券
                    CouponUserModel::update(['status'=>0],[
                        'id' => $model['coupon_id']
                    ]);
                }

            }
        }
    }



    /**
     * 确认订单
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function sureOrder(BaseModel $user_model,$id)
    {
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_HANDLE_SURE,$handle_action))   throw new \Exception('订单状态未处于可确认状态');

        if($user_model instanceof SysManagerModel){
            //管理员
//            $user_model = UserModel::find($model['uid']);
        }else{
//            if(empty($model) || $model['uid']!=$user_model->id)   throw new \Exception('订单数据异常:2');

        }
        try{
            \think\facade\Db::startTrans();
            $row_num = self::where(['id'=>$id])->update(['is_sure'=>1,'sure_time'=>date('Y-m-d H:i:s')]);

            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollback();
            throw new \Exception($e->getMessage());
        }

        //发送短信
        $modelUser = UserModel::find($model['uid']);
        if(!empty($modelUser)){
            try{
                UserNoticeModel::recordLog("订单进度","您好，您预定的套餐为：{$model['goods_name']}，技师已经成功接单",$model['id'],$modelUser['id'],1,0);
            }catch (\Exception $e){

            }

        }

        return self::find($id);
    }

    /**
     * 确认出发
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function sendOrder(BaseModel $user_model,$id)
    {
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_HANDLE_SEND,$handle_action))   throw new \Exception('订单状态未处于可出发状态');

        if($user_model instanceof SysManagerModel){
            //管理员
//
        }else{
//            if(empty($model) || $model['uid']!=$user_model->id)   throw new \Exception('订单数据异常:2');

        }
        try{
            \think\facade\Db::startTrans();
            $row_num = self::where(['id'=>$id])->update(['is_send'=>1,'send_time'=>date('Y-m-d H:i:s')]);

            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollback();
            throw new \Exception($e->getMessage());
        }

        //发送短信
        $modelUser = UserModel::find($model['uid']);
        if(!empty($modelUser)){
            try{
                UserNoticeModel::recordLog("订单进度","您好，您预定的技师已经出发，请确认目的地无误",$model['id'],$modelUser['id'],1,0);
            }catch (\Exception $e){

            }

        }

        return self::find($id);
    }
    /**
     * 确认到达
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function receiveOrder(BaseModel $user_model,$id)
    {
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_HANDLE_RECEIVE,$handle_action))   throw new \Exception('订单状态未处于可到达状态');

        if($user_model instanceof SysManagerModel){
            //管理员
//            $user_model = UserModel::find($model['uid']);
        }else{
//            if(empty($model) || $model['uid']!=$user_model->id)   throw new \Exception('订单数据异常:2');

        }
        try{
            \think\facade\Db::startTrans();
            $row_num = self::where(['id'=>$id])->update(['is_receive'=>1,'rec_time'=>date('Y-m-d H:i:s')]);

            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollback();
            throw new \Exception($e->getMessage());
        }


        //发送短信
        $modelUser = UserModel::find($model['uid']);
        if(!empty($modelUser)){
            try{
                UserNoticeModel::recordLog("订单进度","您好，您预定的技师已经抵达，请保持电话畅通",$model['id'],$modelUser['id'],1,0);
            }catch (\Exception $e){

            }

        }


        return self::find($id);
    }
    /**
     * 确认到达
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function serviceOrder(BaseModel $user_model,$id)
    {
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_HANDLE_SERVICE,$handle_action))   throw new \Exception('订单状态未处于可服务状态');

        if($user_model instanceof SysManagerModel){
            //管理员
//            $user_model = UserModel::find($model['uid']);
        }else{
//            if(empty($model) || $model['uid']!=$user_model->id)   throw new \Exception('订单数据异常:2');

        }
        try{
            \think\facade\Db::startTrans();
            $service_datetime = OrderServiceTimeModel::addService($model);
            $row_num = self::where(['id'=>$id])->update(['is_service'=>1,'service_time'=>$service_datetime]);

            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollback();
            throw new \Exception($e->getMessage());
        }
        return self::find($id);
    }
    /**
     * 完成
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function completeOrder(BaseModel $user_model,$id)
    {
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
//        if(!in_array(self::ORDER_HANDLE_COMPLETE,$handle_action))   throw new \Exception('订单状态未处于可到达状态');

        if($user_model instanceof SysManagerModel){
            //管理员
//            $user_model = UserModel::find($model['uid']);
        }else{
//            if(empty($model) || $model['uid']!=$user_model->id)   throw new \Exception('订单数据异常:2');
        }

        $model->_orderComplete();

        return self::find($id);
    }

    /**
     * 删除订单
     * @param BaseModel $user_model 用户|管理员模型
     * @param int|array $id 订单id
     * @throws
     * */
    public static function del(BaseModel $user_model,$id)
    {
        if(empty($id))  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $del_ids = [];
        if(is_array($id)){
            $del_ids = $id;
        }else{
            $del_ids = [$id];
        }

        foreach ($del_ids as $id){
            $model = self::find($id);
            if(empty($model))  throw new \Exception('订单异常:1');

            list($status_name,$handle_action) = $model->getStatusName();
            if(!in_array(self::ORDER_HANDLE_DEL,$handle_action))   throw new \Exception('订单状态未处于可取消状态');


            $exr_num = self::where(['id'=>$id])->whereNull('delete_time')->update(['delete_time'=>time()]);
        }

    }



    /**
     * 取消订单
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function cancel(BaseModel $user_model,$id,array $input_data = [])
    {
        $is_refuse = $input_data['is_refuse']??0;
        $content = trim($input_data['content']??'');
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
        if(!(in_array(self::ORDER_HANDLE_CANCEL,$handle_action) || in_array(self::ORDER_HANDLE_CANCEL_MASTER,$handle_action)))   throw new \Exception('订单状态未处于可取消状态');

        if($user_model instanceof SysManagerModel){
            //管理员
//            $user_model = UserModel::find($model['uid']);
        }else{
//            if(empty($model) || $model['uid']!=$user_model->id)   throw new \Exception('订单数据异常:2');
        }

        try{
            \think\facade\Db::startTrans();
            $update = ['is_cancel'=>1,'cancel_time'=>time(), 'status'=>2];
            if($is_refuse==1){
                $update['is_refuse'] = 1;
                $update['cancel_reason'] = $content;
                $update['refuse_time'] = date('Y-m-d H:i:s');
            }
            $row_num = self::where(['id'=>$id,'is_cancel'=>0])->update($update);
            if(!empty($row_num)){
                if($model['is_pay']){
                    $model->setAttr('back_money',$model['pay_money']);
                    $model->save();

                    $model->backMoney($model['pay_money']);

                }
            }



            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollback();
            throw new \Exception($e->getMessage());
        }

        //触发取消订单事件
        $model->trigger('orderBackHandle');
        return self::find($id);
    }

    public static function handleBackMoney(array $input_data = [])
    {
        $order_id = $input_data['order_id']??'';
        $money = floatval($input_data['money']??'');
        $remark = trim($input_data['remark']??'');
        if(empty($order_id)) throw new \Exception("参数异常:order_id");
        if(empty($money)) throw new \Exception("请输入退款金额");
        if($money<0) throw new \Exception("请输入退款金额必须为正数");
        $order_model = self::find($order_id);
        if(empty($order_model)) throw new \Exception("订单信息异常");
        if(empty($order_model['is_pay'])) throw new \Exception("未付款订单无法进行此操作");
        $back_money = empty($order_model['back_money'])?0:$order_model['back_money'];
        $reduce_money =  $order_model['pay_money']-$back_money; //剩余可退金额
        if($reduce_money < $money )throw new \Exception("已超出可退款额度,剩余可退款额度:{$reduce_money}");
        $pay_way_info = self::getPropInfo('fields_pay_way',$order_model['pay_way']);
        $class = $pay_way_info['class']??'';

        if(!empty($class)){
            list($third_code,$third_state,$third_message,$third_result) = $class::backMoney($order_model,$money);
        }else{
            $third_state = 2;
            $third_message = "非第三方退款";
        }
        if($third_state==1 || $third_state==2){ //退款成功/处理中
            $order_model->setAttr('back_money',$money+$back_money);
            $order_model->save();
            //增加用户购买次数
            !empty($order_model['uid']) && UserModel::where(['id'=>$order_model['uid']])->update(['order_back_num'=>Db::raw('order_back_num + 1')]);

            $order_model->sendEmail('back_money');
        }

        OrderBackMoneyLogsModel::record($order_id,$order_model['pay_way'],$money,[
            'third_code'=>$third_code??'','third_state'=>$third_state??0,'third_message'=>$third_message??'','third_result'=>$third_result??[],
            'remark'=>$remark,
        ]);
    }

    public static function modifyCustomerRemark(array $input_data = [])
    {
        $id = $input_data['id']??'';
        $customer_remark = trim($input_data['customer_remark']??'');

        if(empty($id)) throw new \Exception("参数异常:id");
        if(empty($customer_remark)) throw new \Exception("请输入退款金额");

        $order_model = self::find($id);
        if(empty($order_model)) throw new \Exception("订单信息异常");
        if(empty($order_model['is_pay'])) throw new \Exception("未付款订单无法进行此操作");
        try{
            $change_data = MaBangErp::modifyOrder($order_model,[
                'remark'=>$order_model['remark'].';;'.$customer_remark
            ]);
        }catch (\Exception $e){
            $change_data = [$e->getMessage()];
        }

        $old_mb_change_record = empty($order_model['mb_change_record']) ? [] : json_decode($order_model['mb_change_record']);
        array_push($old_mb_change_record,$change_data);
        $order_model->setAttrs([
            'mb_change_record' => json_encode($old_mb_change_record, JSON_UNESCAPED_UNICODE),
            'customer_remark' => $customer_remark,
        ]);
        $order_model->save();
    }

    //订单退款操作
    public function backMoney($force_money = null)
    {



    }


    /**
     * 收货--订单
     * @param UserModel $user_model |null 用户模型
     * @param $id int 订单id
     * @param $model self|null 是否强制收货订单
     * @throws
     * */
    public static function receive(BaseModel $user_model = null, $id = 0)
    {
        $model = self::find($id);
        if (empty($model)) throw new \Exception('订单异常:1');
        list($status_name,$handle_action) = $model->getStatusName();


        $model->_orderComplete();
        return self::find($id);
    }

    /**
     * 取消订单
     * @param BaseModel $user_model 用户模型
     * @param $id int 订单id
     * @throws
     * */
    public static function forceBack(BaseModel $user_model,$id,array $input_data = [])
    {
        $content = trim($input_data['content']??'');
        $opt_action = trim($input_data['opt_action']??'');
        if(empty($id) || !is_numeric($id) || $id<=0)  throw new \Exception('订单信息异常:id');
        if(empty($user_model))  throw new \Exception('用户资料异常');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单异常:1');

        list($status_name,$handle_action) = $model->getStatusName();
//        if(!in_array(self::ORDER_HANDLE_FORCE_BACK,$handle_action))   throw new \Exception('订单状态未处于可取消状态');
        if(!in_array($opt_action, $handle_action))   throw new \Exception('订单状态未处于可取消状态');

        if($user_model instanceof SysManagerModel){
            //管理员
        }else{
        }

        try{
            \think\facade\Db::startTrans();
            $row_num = self::where(['id'=>$id,'is_force_back'=>0])->update(['is_force_back'=>1,'force_back_time'=>date('Y-m-d H:i:s'), 'status'=>2]);
            if($row_num){

                $back_money = $model['pay_money']; //实际退款金额

                
                $model->setAttr('back_money',$back_money );
                $model->save();
                $model->backMoney($back_money );



            }

            \think\facade\Db::commit();
        }catch (\Exception $e){
            \think\facade\Db::rollback();
            throw new \Exception($e->getMessage());
        }

        //触发取消订单事件
        return self::find($id);
    }


    /**
     * 确认付款
     * @param BaseModel $manager 管理员模型
     * @param int $id 操作订单id
     * @throws
     * */
    public static function surePay(BaseModel $manager ,$id)
    {
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单信息异常');
        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_HANDLE_PAY,$handle_action))   throw new \Exception('订单状态未处于可完成状态');

        //确认支付
        $model->_sure_pay();
        return self::find($id);
    }


    /**
     * 售后申请
     * @param UserModel $user_model 管理员模型
     * @param int $id 操作订单id
     * @throws
     * */
    public static function saleReq(UserModel $user_model ,array $input_data = [])
    {
        $order_id = $input_data['order_id']??0;
        $reason = trim($input_data['reason']??'');
        if(empty($order_id))  throw new \Exception('参数异常:order_id');
        if(empty($reason))  throw new \Exception('请选择退款理由');

        $model = self::find($order_id);
        if(empty($model))  throw new \Exception('订单信息异常');
        list($status_name,$handle_action) = $model->getStatusName();
        if(!(in_array(self::ORDER_BACK_START, $handle_action) || in_array(self::ORDER_BACK_RETRY, $handle_action)))   throw new \Exception('订单状态未处于可售后状态');

        $model->setAttrs([
            'is_back'=>1,
            'back_reason'=>$reason,
            'back_req_time'=>date('Y-m-d H:i:s'),
        ]);
        $model->save();
    }
    /**
     * 售后申请
     * @param UserModel $user_model 管理员模型
     * @param int $id 操作订单id
     * @throws
     * */
    public static function saleCancel(UserModel $user_model ,array $input_data = [])
    {
        $order_id = $input_data['order_id']??0;
        if(empty($order_id))  throw new \Exception('参数异常:order_id');

        $model = self::find($order_id);
        if(empty($model))  throw new \Exception('订单信息异常');
        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_BACK_CANCEL, $handle_action))   throw new \Exception('订单状态未处于可取消状态');

        $model->setAttrs([
            'is_back'=>0,
            'back_cancel_time'=>date('Y-m-d H:i:s'),
        ]);
        $model->save();
    }

    /**
     * 售后审核
     * @throws
     * */
    public static function saleAfterAuth(array $input_data = [])
    {
        $id = $input_data['id']??0;
        $back_money = $input_data['back_money']??0;
        $state = $input_data['state']??0;
        $state = $state==1 ? 1: 2;
        $content = trim($input_data['content']??'');
        if(empty($back_money))  throw new \Exception('请输入退款金额');
        if(empty($id))  throw new \Exception('参数异常:order_id');
        $model = self::find($id);
        if(empty($model))  throw new \Exception('订单信息异常');
        list($status_name,$handle_action) = $model->getStatusName();
        if(!in_array(self::ORDER_BACK_AUTH, $handle_action))   throw new \Exception('订单状态未处于审核完成状态');

        if($back_money>$model['pay_money'])  throw new \Exception('退款金额不得超过支付金额');
        try{
            Db::startTrans();
            if($state==1){ //通过
                //进行退款流程

            }

            $model->setAttrs([
                'is_back'=>$state==1 ? 2 : 3,
                'back_money'=> $back_money,
                'back_intro'=> $content,
                'back_complete_time'=>date('Y-m-d H:i:s'),
            ]);
            $model->save();
            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
        }

        return self::find($id);
    }


    //列表统计
    public static function echarts(array $php_input)
    {
        $date_mode = $php_input['date_mode'] ?? 'day';
        $where = [];
        $group = 'op_time';
        $field = ' count(*) as count_num,sum(pay_money) as sum_pay_money ';
        if ($date_mode == 'day') { //按小时计算
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d'))];
            $field .= ' ,FROM_UNIXTIME(create_time,\'%H\') as op_time';
        } elseif ($date_mode == 'week') {
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 7 * 84600];
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
        } elseif ($date_mode == 'month') {
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 30 * 84600];
        } elseif ($date_mode == 'month60') {
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 60 * 84600];
        } elseif ($date_mode == 'year') {
            $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
            $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 365 * 84600];
        }
        $date_list = get_op_time($date_mode);
        $list = [];
        foreach ($date_list as $vo) {
            $list[$vo] = [
                'name' => $vo,
                'value' => 0
            ];
        }
        list($cond_where,$cond_whereOr)=self::getStateWhere('sure_pay');
        Db::table('order')->field($field)->where($cond_where)->where(function($query)use($cond_whereOr){
            $query->whereOr($cond_whereOr);
        })->where($where)
            ->group($group)->select()->each(function ($item) use (&$list, $date_list) {
                $key = $item['op_time'];
                $list[$key]['value'] = $item['sum_pay_money'];
            });

        return [array_column($list, 'name'), array_column($list, 'value')];
//        self::field($field)->where($where)->gourp($group)->select();

    }




    /**
     * 交易完成
     * @throws
     * */
    private function _orderComplete()
    {
        $time = date('Y-m-d H:i:s');
        try{
            Db::startTrans();


            $update = [
                'is_complete'=>1,
                'complete_time'=>$time,
                'status'=>3,
                'is_receive'=>1,
                'rec_time'=> $time,
            ];
            $update_num = self::where(['id'=>$this['id'],'complete_time'=>null])->update($update);

            //开启评论
            OrderGoodsModel::where(['oid'=>$this['id']])->update([
                'comment_state'=>1,
            ]);

            Db::commit();
        }catch (\Exception $e){
            Db::rollback();
            throw new \Exception( $e->getMessage());
        }


    }


    //订单支付
    public function _sure_pay($pay_way=0)
    {
        $order_type = (int)$this->getAttr('type');
        $current_datetime = date('Y-m-d H:i:s');
        $pay_info = $this->getAttr('pay_info');
        $paypal_capture_id = $this->getAttr('paypal_capture_id');

        self::where(['id'=>$this['id']])->update([
            'pay_way'=>$pay_way,
            'pay_info'=> empty($pay_info)?[]:json_encode($pay_info),
            'paypal_capture_id'=> empty($paypal_capture_id)?null:$paypal_capture_id,
            'is_pay'=>1,
            'pay_time'=> $current_datetime,
            'status'=>1]);

        $queue_type = $order_type;

        OrderGoodsModel::where(['oid'=>$this['id']])->update([
            'is_pay'=>1,
            'pay_time'=>$current_datetime,
        ]);


        //创建商户提现记录
        try{


            //创建消费记录
            SysMoneyQueueModel::producer($queue_type,$this['uid'],$this['id'],$this['goods_money'],'单号:'.$this['no'],[
                'order_extra'=>$this['extra'],
                'order_id'=>$this['id'],
                'pay_way'=>$pay_way,
                'order_no'=>$this['no'],
                'order_type'=>$order_type,
                'goods_name'=>$this['goods_name'],

                'coupon_id'=>$this['coupon_id'],
                'coupon_dis_money'=>$this['coupon_dis_money'],

                'integral'=>$this['integral'],
                'integral_money'=>$this['integral_money'],

                'master_ser_money'=> $this['master_ser_money'],
                'master_car_money'=> $this['master_car_money'],


                'order_money'=>$this['money'],
                'pay_money'=> (string)$this['pay_money'],
                'distance_money'=>$this['distance_money'],
                'commission_uid'=>$this['commission_uid'],
                'commission_money'=>$this['commission_money'],
                'open_vip_day'=>$this['open_vip_day'],
                'mid'=>$this['mid'],
                'mch_id'=>$this['mch_id'],
            ]);

        }catch (\Exception $e){
            $message = $e->getMessage();
            \think\facade\Log::write("_sure_pay,执行异常id:{$this['id']},错误消息:{$message}:line:{$e->getLine()}");
        }

        //交易通知
        $this->trigger('orderPaySuccess');


    }

    public function apiFullInfo()
    {
        return array_merge($this->apiShowInfo(),[
            'sort' => $this['sort'],
            'status' => $this['status'],
            'customer_remark' => $this['customer_remark'],
            'update_time' => $this['update_time'],
        ]);
    }

    public function apiShowInfo()
    {
        $linkServiceTime = $this->getRelation('linkServiceTime');
        //出行方式
        $travel = $this['travel'];
        $travel_info = [];
        $goWayInfo = SysSettingModel::goWayInfo();
        foreach ($goWayInfo as $item){
            if($item['value']==$travel){
                $travel_info = $item;
                break;
            }
        }

        $service_times = [];
        if(!empty($linkServiceTime) && !$linkServiceTime->isEmpty()){
            foreach ($linkServiceTime as $vo){
                $service_times[] = $vo->apiNormalInfo();
            }
        }

        return array_merge($this->apiNormalInfo(),[
            'price_list' => $this->getPriceList(),
            'remark' => (string)$this['remark'],
            'remark_tag' => (string)$this['remark_tag'],
            'sort' => $this['sort'],
            'status' => $this['status'],
            'status_bool' => $this['status']==1,
            'create_time' => $this->getAttr('create_time'),  //创建时间
            'travel'=>$this['travel'],
            'travel_name'=>$travel_info['name']??'',
            'service_times'=>$service_times,

            'is_back'=>(int)$this['is_back'],
            'is_back_name'=> self::getPropInfo('fields_is_back', $this['is_back'],'name'),
            'back_req_time' => $this['back_req_time'],
            'back_reason' => $this['back_reason'],
            'back_car_money' => $this['back_car_money'],
            'back_money' => $this['back_money'],
            'back_cancel_time' => $this['back_cancel_time'],
            'back_complete_time' => $this['back_complete_time'],
            'back_intro' => $this['back_intro'],
        ]);
    }


    public function apiNormalInfo()
    {
        $user_addr = $this->getRelation('linkAddr');
        $linkUser = $this->getRelation('linkUser');
        $linkGoods = $this->getRelation('linkGoods');
        $linkLogistics = $this->getRelation('linkLogistics');

        $goods = [];
        foreach ($linkGoods as $vo){
            if(app()->http->getName()=='admin'){
                array_push($goods,$vo->apiFullInfo());
            }else{
                array_push($goods,$vo->apiNormalInfo());
            }
        }

        list($status_name,$handle_action) = $this->getStatusName();

        return [
            'id'=> $this['id'],
            'no'=> $this['no'],
            'type'=> (int)$this['type'],
            'type_name'=> self::getPropInfo('fields_type',$this['type'],'name'),
            'total_num'=> $this['total_num'],
            'email'=> (string)$this['email'],
            'money'=> $this['money'],
            'goods_money'=> $this['goods_money'],
            'dis_money'=> $this['dis_money'],
            'tip_money'=> $this['tip_money'],
            'pay_money'=> (string)$this['pay_money'],
            'distance'=> (string)$this['distance'],
            'distance_money'=> $this['distance_money'],
            'pay_way' => $this['pay_way'],
            'pay_way_name' => self::getPropInfo('fields_pay_way', $this['pay_way'],'name'),
            'pay_time' => empty($this['pay_time'])?'':$this['pay_time'],  //支付金额
            'status'=> (int)$this['status'],
            'status_name' => $status_name,
            'handle_action' => $handle_action,
            'ser_start_time' => $this['ser_start_time'],
            'ser_minute' => $this['ser_minute'],
            'ser_end_time' => $this['ser_end_time'],
            'cancel_time' => empty($this['cancel_time'])?'':date('Y-m-d H:i:s'),
            'cancel_reason' => (string)$this['cancel_reason'],
            'reminder_time' => $this['reminder_time'],

            'is_sure' => (int)$this['is_sure'],
            'sure_time' => $this['sure_time'],
            'is_send' => (int)$this['is_send'],
            'send_time' => $this['send_time'],
            'is_receive' => (int)$this['is_receive'],
            'rec_time' => $this['rec_time'],
            'is_service' => (int)$this['is_service'],
            'service_time' => $this['service_time'],
            'is_complete' => (int)$this['is_complete'],
            'complete_time' => $this['complete_time'],



            'user_id' => (int)$linkUser['id'],
            'user_name' => (string)$linkUser['name'],
            'user_avatar' => (string)$linkUser['avatar'],
            'user_phone' => (string)$linkUser['phone'],

            'user_addr'=>empty($user_addr)?(object)[]:$user_addr->apiNormalInfo(),

            'goods_list'=>$goods,

            'logistics'=>empty($linkLogistics)?(object)[]:$linkLogistics->apiNormalInfo(),

        ];
    }

    public function linkServiceTime()
    {
        return $this->hasMany(OrderServiceTimeModel::class,'oid')->where([['status','<>',0]]);
    }
    public function linkGoods()
    {
        return $this->hasMany(OrderGoodsModel::class,'oid');
    }
    public function linkAddr()
    {
        return $this->hasOne(OrderAddrModel::class,'oid');
    }
    public function linkLogistics()
    {
        return $this->hasOne(OrderLogisticsModel::class,'oid')->order('id desc');
    }
    public function linkUser()
    {
        return $this->belongsTo(UserModel::class,'uid');
    }
}